Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


nomadnet/ui/textui/Guide.py f8c57e675e6f7aa9a811c65d21fbe873f42736b0 (f8c57e67) Text, 75.04 KB

Tff7b72import T7ee787RNS
Tff7b72import T7ee787urwid
Tff7b72import T7ee787nomadnet
Tff7b72from T7ee787nomadnetT7ee787.T7ee787vendorT7ee787.T7ee787additional_urwid_widgets Tff7b72import Te6edf3IndicativeListBoxTb4b4b4, Te6edf3MODIFIER_KEY
Tff7b72from T7ee787.T7ee787MicronParser Tff7b72import Te6edf3markup_to_attrmaps
Tff7b72from T7ee787nomadnetT7ee787.T7ee787vendorT7ee787.T7ee787Scrollable Tff7b72import Tff7b72*

Tff7b72class T56d364GuideDisplayShortcutsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Te6edf3g Tff7b72= Te6edf3appTff7b72.Td2a8ffuiTff7b72.Td2a8ffglyphs

Tff7b72selfTff7b72.Td2a8ffwidget Tff7b72= Te6edf3urwidTff7b72.Td2a8ffAttrMapTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffPaddingTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffTextTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3alignTff7b72=Te6edf3urwidTff7b72.Td2a8ffLEFTTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffshortcutbarTa5d6ff"Tb4b4b4)

Tff7b72class T56d364ListEntryTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffTextTb4b4b4)Tb4b4b4:
Te6edf3_selectable Tff7b72= Tff7b72True

Te6edf3signals Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffclickTa5d6ff"Tb4b4b4]

Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
T8b949e"""
Send 'click' signal on 'activate' command.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72!= Te6edf3urwidTff7b72.Td2a8ffACTIVATETb4b4b4:
Tff7b72return Te6edf3key

Tff7b72selfTff7b72.Td2a8ff_emitTb4b4b4(Ta5d6ff'Ta5d6ffclickTa5d6ff'Tb4b4b4)

Tff7b72def Td2a8ffmouse_eventTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3xTb4b4b4, Te6edf3yTb4b4b4, Te6edf3focusTb4b4b4)Tb4b4b4:
T8b949e"""
Send 'click' signal on button 1 press.
"""
Tff7b72if Te6edf3button Tff7b72!= T79c0ff1 Tff7b72or Tff7b72not Te6edf3urwidTff7b72.Td2a8ffutilTff7b72.Td2a8ffis_mouse_pressTb4b4b4(Te6edf3eventTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False

Tff7b72selfTff7b72.Td2a8ff_emitTb4b4b4(Ta5d6ff'Ta5d6ffclickTa5d6ff'Tb4b4b4)
Tff7b72return Tff7b72True

Tff7b72class T56d364SelectTextTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffTextTb4b4b4)Tb4b4b4:
Te6edf3_selectable Tff7b72= Tff7b72True

Te6edf3signals Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffclickTa5d6ff"Tb4b4b4]

Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
T8b949e"""
Send 'click' signal on 'activate' command.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72!= Te6edf3urwidTff7b72.Td2a8ffACTIVATETb4b4b4:
Tff7b72return Te6edf3key

Tff7b72selfTff7b72.Td2a8ff_emitTb4b4b4(Ta5d6ff'Ta5d6ffclickTa5d6ff'Tb4b4b4)

Tff7b72def Td2a8ffmouse_eventTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3xTb4b4b4, Te6edf3yTb4b4b4, Te6edf3focusTb4b4b4)Tb4b4b4:
T8b949e"""
Send 'click' signal on button 1 press.
"""
Tff7b72if Te6edf3button Tff7b72!= T79c0ff1 Tff7b72or Tff7b72not Te6edf3urwidTff7b72.Td2a8ffutilTff7b72.Td2a8ffis_mouse_pressTb4b4b4(Te6edf3eventTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False

Tff7b72selfTff7b72.Td2a8ff_emitTb4b4b4(Ta5d6ff'Ta5d6ffclickTa5d6ff'Tb4b4b4)
Tff7b72return Tff7b72True

Tff7b72def Td2a8ff_rows_aboveTb4b4b4(Te6edf3attrmapsTb4b4b4, Te6edf3indexTb4b4b4, Te6edf3colsTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3index Tff7b72<Tff7b72= T79c0ff0 Tff7b72or Tff7b72not Te6edf3attrmapsTb4b4b4:
Tff7b72return T79c0ff0
Te6edf3total Tff7b72= T79c0ff0
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tffa657minTb4b4b4(Te6edf3indexTb4b4b4, Tffa657lenTb4b4b4(Te6edf3attrmapsTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3total Tff7b72+Tff7b72= Te6edf3attrmapsTb4b4b4[Te6edf3iTb4b4b4]Tff7b72.Td2a8ffrowsTb4b4b4(Tb4b4b4(Te6edf3colsTb4b4b4,Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3total Tff7b72+Tff7b72= T79c0ff1
Tff7b72return Te6edf3total


Tff7b72class T56d364GuideColumnsTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffColumnsTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
T8b949e# TODO: Scroll handling is currently very weird
T8b949e# in the guide reader. When using page up/down
T8b949e# or mouse scroll, the actual cursor position
T8b949e# does not follow the scroll, as it does in the
T8b949e# browser. If you scroll down, and then use the
T8b949e# arrow keys, the position jumps back up to
T8b949e# where you "left" the cursor.
T8b949e# There's handling for this in the Browser code
T8b949e# but I don't have time to port it over here at
T8b949e# this point. If someone else takes that one up
T8b949e# it's :) :) :)
Tff7b72return Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffkeypressTb4b4b4(Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)


Tff7b72class T56d364GuideLinkDelegateTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4, Te6edf3readerTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffreader Tff7b72= Te6edf3reader
Tff7b72selfTff7b72.Td2a8fflast_keypress Tff7b72= T79c0ff0

Tff7b72def Td2a8ffmarked_linkTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3targetTb4b4b4, Te6edf3fieldsTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ffmicron_released_focusTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreaderTff7b72.Td2a8fffocus_topicsTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffhandle_linkTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3targetTb4b4b4, Te6edf3fieldsTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3targetTb4b4b4:
Tff7b72return
Tff7b72if Te6edf3targetTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff#Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffreader Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreaderTff7b72.Td2a8ffjump_to_anchorTb4b4b4(Te6edf3targetTb4b4b4[T79c0ff1Tb4b4b4:Tb4b4b4]Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffGuide anchor jump failed: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffmain_displayTff7b72.Td2a8ffshow_networkTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffmain_displayTff7b72.Td2a8ffsub_displaysTff7b72.Td2a8ffnetwork_displayTff7b72.Td2a8ffbrowserTff7b72.Td2a8ffhandle_linkTb4b4b4(Te6edf3targetTb4b4b4, Te6edf3fieldsTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not open guide link: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72class T56d364GuideEntryTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWidgetWrapTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4, Te6edf3parentTb4b4b4, Te6edf3readerTb4b4b4, Te6edf3topic_nameTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffparent Tff7b72= Te6edf3parent
Tff7b72selfTff7b72.Td2a8ffreader Tff7b72= Te6edf3reader
Tff7b72selfTff7b72.Td2a8fflast_keypress Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftopic_name Tff7b72= Te6edf3topic_name
Te6edf3g Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffglyphs

Te6edf3widget Tff7b72= Te6edf3ListEntryTb4b4b4(Te6edf3topic_nameTb4b4b4)
Te6edf3urwidTff7b72.Td2a8ffconnect_signalTb4b4b4(Te6edf3widgetTb4b4b4, Ta5d6ff"Ta5d6ffclickTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffdisplay_topicTb4b4b4, Tff7b72selfTff7b72.Td2a8fftopic_nameTb4b4b4)

Te6edf3style Tff7b72= Ta5d6ff"Ta5d6fftopic_list_normalTa5d6ff"
Te6edf3focus_style Tff7b72= Ta5d6ff"Ta5d6fflist_focusTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffdisplay_widget Tff7b72= Te6edf3urwidTff7b72.Td2a8ffAttrMapTb4b4b4(Te6edf3widgetTb4b4b4, Te6edf3styleTb4b4b4, Te6edf3focus_styleTb4b4b4)
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffdisplay_widgetTb4b4b4)

Tff7b72def Td2a8ffdisplay_topicTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3topicTb4b4b4)Tb4b4b4:
Te6edf3markup Tff7b72= Te6edf3TOPICSTb4b4b4[Te6edf3topicTb4b4b4]
Te6edf3attrmaps Tff7b72= Te6edf3markup_to_attrmapsTb4b4b4(Te6edf3markupTb4b4b4, Te6edf3url_delegateTff7b72=Te6edf3GuideLinkDelegateTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3readerTff7b72=Tff7b72selfTff7b72.Td2a8ffreaderTb4b4b4)Tb4b4b4)

Te6edf3topic_position Tff7b72= Tff7b72None
Te6edf3index Tff7b72= T79c0ff0
Tff7b72for Te6edf3topic Tff7b72in Tff7b72selfTff7b72.Td2a8ffparentTff7b72.Td2a8fftopic_listTb4b4b4:
Te6edf3widget Tff7b72= Te6edf3topicTff7b72.Td2a8ff_original_widget
Tff7b72if Te6edf3widgetTff7b72.Td2a8fftopic_name Tff7b72== Tff7b72selfTff7b72.Td2a8fftopic_nameTb4b4b4:
Te6edf3topic_position Tff7b72= Te6edf3index
Te6edf3index Tff7b72+Tff7b72= T79c0ff1

Tff7b72if Te6edf3topic_position Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffparentTff7b72.Td2a8ffilbTff7b72.Td2a8ffselect_itemTb4b4b4(Te6edf3topic_positionTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffreaderTff7b72.Td2a8ffset_content_widgetsTb4b4b4(Te6edf3attrmapsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffreaderTff7b72.Td2a8fffocus_readerTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffmicron_released_focusTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreaderTff7b72.Td2a8fffocus_topicsTb4b4b4(Tb4b4b4)

Tff7b72class T56d364TopicListTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWidgetWrapTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4, Te6edf3guide_displayTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Te6edf3g Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffglyphs

Tff7b72selfTff7b72.Td2a8fffirst_run_entry Tff7b72= Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffFirst RunTa5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8fftopic_list Tff7b72= Tb4b4b4[
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffIntroductionTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffConcepts & TerminologyTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffChannels & RRCTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffInterfacesTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffHosting a NodeTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffConfiguration OptionsTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffKeyboard ShortcutsTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffMarkupTa5d6ff"Tb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8fffirst_run_entryTb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffNetwork ConfigurationTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffDisplay TestTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3GuideEntryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3guide_displayTb4b4b4, Ta5d6ff"Ta5d6ffCredits & LicensesTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4]

Tff7b72selfTff7b72.Td2a8ffilb Tff7b72= Te6edf3IndicativeListBoxTb4b4b4(
Tff7b72selfTff7b72.Td2a8fftopic_listTb4b4b4,
Te6edf3initialization_is_selection_changeTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3highlight_offFocusTff7b72=Ta5d6ff"Ta5d6fflist_off_focusTa5d6ff"
Tb4b4b4)

Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Te6edf3urwidTff7b72.Td2a8ffLineBoxTb4b4b4(Tff7b72selfTff7b72.Td2a8ffilbTb4b4b4, Te6edf3titleTff7b72=Ta5d6ff"Ta5d6ffTopicsTa5d6ff"Tb4b4b4)Tb4b4b4)


Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3key Tff7b72== Ta5d6ff"Ta5d6ffupTa5d6ff" Tff7b72and Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffilbTff7b72.Td2a8fffirst_item_is_selectedTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffuiTff7b72.Td2a8ffmain_displayTff7b72.Td2a8ffframeTff7b72.Td2a8fffocus_position Tff7b72= Ta5d6ff"Ta5d6ffheaderTa5d6ff"
Tff7b72return Tffa657superTb4b4b4(Te6edf3TopicListTb4b4b4, Tff7b72selfTb4b4b4)Tff7b72.Td2a8ffkeypressTb4b4b4(Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)

Tff7b72class T56d364GuideDisplayTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3list_width Tff7b72= T79c0ff0.33

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Te6edf3g Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffglyphs

Te6edf3topic_text Tff7b72= Te6edf3urwidTff7b72.Td2a8ffTextTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff No topic selectedTa5d6ff"Tb4b4b4, Te6edf3alignTff7b72=Te6edf3urwidTff7b72.Td2a8ffLEFTTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffleft_area Tff7b72= Te6edf3TopicListTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Tff7b72selfTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffright_area Tff7b72= Te6edf3urwidTff7b72.Td2a8ffLineBoxTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffFillerTb4b4b4(Te6edf3topic_textTb4b4b4, Te6edf3urwidTff7b72.Td2a8ffTOPTb4b4b4)Tb4b4b4)


Tff7b72selfTff7b72.Td2a8ffcolumns Tff7b72= Te6edf3GuideColumnsTb4b4b4(
Tb4b4b4[
Tb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWEIGHTTb4b4b4, Te6edf3GuideDisplayTff7b72.Td2a8fflist_widthTb4b4b4, Tff7b72selfTff7b72.Td2a8ffleft_areaTb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWEIGHTTb4b4b4, T79c0ff1Tff7b72-Te6edf3GuideDisplayTff7b72.Td2a8fflist_widthTb4b4b4, Tff7b72selfTff7b72.Td2a8ffright_areaTb4b4b4)
Tb4b4b4]Tb4b4b4,
Te6edf3dividecharsTff7b72=T79c0ff0Tb4b4b4, Te6edf3focus_columnTff7b72=T79c0ff0
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8ffguide_display Tff7b72= Tff7b72self

Tff7b72selfTff7b72.Td2a8ffshortcuts_display Tff7b72= Te6edf3GuideDisplayShortcutsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffwidget Tff7b72= Tff7b72selfTff7b72.Td2a8ffcolumns

Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fffirstrunTb4b4b4:
Te6edf3entry Tff7b72= Tff7b72selfTff7b72.Td2a8ffleft_areaTff7b72.Td2a8fffirst_run_entry
Te6edf3entryTff7b72.Td2a8ffdisplay_topicTb4b4b4(Te6edf3entryTff7b72.Td2a8ffdisplay_topicTb4b4b4, Te6edf3entryTff7b72.Td2a8fftopic_nameTb4b4b4)

Tff7b72def Td2a8ffset_content_widgetsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3new_contentTb4b4b4)Tb4b4b4:
Te6edf3options Tff7b72= Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8ffoptionsTb4b4b4(Te6edf3width_typeTff7b72=Te6edf3urwidTff7b72.Td2a8ffWEIGHTTb4b4b4, Te6edf3width_amountTff7b72=T79c0ff1Tff7b72-Te6edf3GuideDisplayTff7b72.Td2a8fflist_widthTb4b4b4, Te6edf3box_widgetTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3pile Tff7b72= Te6edf3urwidTff7b72.Td2a8ffPileTb4b4b4(Te6edf3new_contentTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_content_attrmaps Tff7b72= Te6edf3new_content
Tff7b72selfTff7b72.Td2a8ff_content_scrollable Tff7b72= Te6edf3ScrollableTb4b4b4(Te6edf3pileTb4b4b4)
Te6edf3pileTff7b72.Td2a8ffautomove_cursor_on_scroll Tff7b72= Tff7b72True
Te6edf3content Tff7b72= Te6edf3urwidTff7b72.Td2a8ffLineBoxTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffAttrMapTb4b4b4(Te6edf3ScrollBarTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_content_scrollableTb4b4b4, Te6edf3thumb_charTff7b72=Ta5d6ff"Tffea00\u2503Ta5d6ff"Tb4b4b4, Te6edf3trough_charTff7b72=Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffscrollbarTa5d6ff"Tb4b4b4)Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8ffcontentsTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3contentTb4b4b4, Te6edf3optionsTb4b4b4)

Tff7b72def Td2a8ffjump_to_anchorTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3nameTb4b4b4)Tb4b4b4:
Te6edf3scrollable Tff7b72= Tffa657getattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ff_content_scrollableTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3attrmaps Tff7b72= Tffa657getattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ff_content_attrmapsTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3scrollable Tff7b72is Tff7b72None Tff7b72or Te6edf3attrmaps Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return
Te6edf3anchors Tff7b72= Tffa657getattrTb4b4b4(Te6edf3attrmapsTb4b4b4, Ta5d6ff"Ta5d6ffanchorsTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4) Tff7b72or Tb4b4b4{Tb4b4b4}
Te6edf3header_rows Tff7b72= Tffa657getattrTb4b4b4(Te6edf3attrmapsTb4b4b4, Ta5d6ff"Ta5d6ffheader_rowsTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4) Tff7b72or Tb4b4b4[Tb4b4b4]
Te6edf3cols Tff7b72= Tff7b72selfTff7b72.Td2a8ff_content_colsTb4b4b4(Tb4b4b4)
Te6edf3target_idx Tff7b72= Tff7b72None
Tff7b72if Te6edf3nameTb4b4b4:
Te6edf3target_idx Tff7b72= Te6edf3anchorsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3nameTb4b4b4)
Tff7b72if Te6edf3target_idx Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return
Tff7b72elseTb4b4b4:
Tff7b72tryTb4b4b4: Te6edf3current Tff7b72= Te6edf3scrollableTff7b72.Td2a8ffget_scrollposTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4: Te6edf3current Tff7b72= T79c0ff0
Tff7b72for Te6edf3hr Tff7b72in Te6edf3header_rowsTb4b4b4:
Tff7b72if Te6edf3_rows_aboveTb4b4b4(Te6edf3attrmapsTb4b4b4, Te6edf3hrTb4b4b4, Te6edf3colsTb4b4b4) Tff7b72> Te6edf3currentTb4b4b4:
Te6edf3target_idx Tff7b72= Te6edf3hr
Tff7b72break
Tff7b72if Te6edf3target_idx Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return
Te6edf3row_offset Tff7b72= Te6edf3_rows_aboveTb4b4b4(Te6edf3attrmapsTb4b4b4, Te6edf3target_idxTb4b4b4, Te6edf3colsTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3scrollableTff7b72.Td2a8ffforce_cursor_update Tff7b72= Tff7b72True
Te6edf3scrollableTff7b72.Td2a8ffanchor_cursor_update Tff7b72= Tff7b72True
Te6edf3scrollableTff7b72.Td2a8ffset_scrollposTb4b4b4(Tffa657intTb4b4b4(Te6edf3row_offsetTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ff_content_colsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3cols Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffuiTff7b72.Td2a8ffloopTff7b72.Td2a8ffscreenTff7b72.Td2a8ffget_cols_rowsTb4b4b4(Tb4b4b4)Tb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3cols Tff7b72= T79c0ff100
Tff7b72tryTb4b4b4:
Te6edf3widths Tff7b72= Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8ffcolumn_widthsTb4b4b4(Tb4b4b4(Te6edf3colsTb4b4b4,Tb4b4b4)Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3widthsTb4b4b4) Tff7b72> T79c0ff1 Tff7b72and Te6edf3widthsTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Tffa657maxTb4b4b4(T79c0ff40Tb4b4b4, Te6edf3widthsTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72- T79c0ff3Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72return Tffa657maxTb4b4b4(T79c0ff40Tb4b4b4, Tffa657intTb4b4b4(Te6edf3cols Tff7b72* Tb4b4b4(T79c0ff1 Tff7b72- Te6edf3GuideDisplayTff7b72.Td2a8fflist_widthTb4b4b4)Tb4b4b4) Tff7b72- T79c0ff3Tb4b4b4)

Tff7b72def Td2a8ffshortcutsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffshortcuts_display

Tff7b72def Td2a8fffocus_topicsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8fffocus_position Tff7b72= T79c0ff0

Tff7b72def Td2a8fffocus_readerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcolumnsTff7b72.Td2a8fffocus_position Tff7b72= T79c0ff1


Te6edf3TOPIC_INTRODUCTION Tff7b72= Ta5d6ff'''Ta5d6ff>Nomad Network

Ta5d6ff`c`*Communicate Freely.`*
Ta5d6ff`a

Ta5d6ffThe intention with this program is to provide a tool to that allows you to build private and resilient communications platforms that are in complete control and ownership of the people that use them.

Ta5d6ffNomad Network is build on LXMF and Reticulum, which together provides the cryptographic mesh functionality and peer-to-peer message routing that Nomad Network relies on. This foundation also makes it possible to use the program over a very wide variety of communication mediums, from packet radio to fiber.

Ta5d6ffNomad Network does not need any connections to the public internet to work. In fact, it doesnTa5d6ff'Ta5d6fft even need an IP or Ethernet network. You can use it entirely over packet radio, LoRa or even serial lines. But if you wish, you can bridge islanded Reticulum networks over the Internet or private ethernet networks, or you can build networks running completely over the Internet. The choice is yours.

Ta5d6ffThe current version of the program should be considered a beta release. The program works well, but there will most probably be bugs and possibly sub-optimal performance in some scenarios. On the other hand, this is the best time to have an influence on the direction of the development of Nomad Network. To do so, join the discussion on the Nomad Network project at `_`F00f`[Aleph git`a8d24177d946de4f1f0a0fe1af9a1338:/page/index.mu]`f`_.

Ta5d6ff'''

Te6edf3TOPIC_SHORTCUTS Tff7b72= Ta5d6ff'''Ta5d6ff>Keyboard Shortcuts

Ta5d6ffThe different sections of the program has a number of keyboard shortcuts mapped, that makes operating and navigating the program easier. The following lists details all mapped shortcuts.

Ta5d6ff>>`!Conversations Window`!
Ta5d6ff>>>Conversation List
Ta5d6ff - Ctrl-N Start a new conversation
Ta5d6ff - Ctrl-E Display and edit selected peer info
Ta5d6ff - Ctrl-X Delete conversation
Ta5d6ff - Ctrl-R Open LXMF syncronisation dialog

Ta5d6ff>>>Conversation Display
Ta5d6ff - Ctrl-D Send message
Ta5d6ff - Ctrl-K Clear input fields
Ta5d6ff - Ctrl-T Toggle message title field
Ta5d6ff - Ctrl-O Toggle sort mode
Ta5d6ff - Ctrl-P Purge failed messages
Ta5d6ff - Ctrl-X Clear conversation history
Ta5d6ff - Ctrl-G Toggle fullscreen conversation
Ta5d6ff - Ctrl-W Close conversation

Ta5d6ff>>`!Network Window`!
Ta5d6ff>>>Browser
Ta5d6ff - Ctrl-D Back
Ta5d6ff - Ctrl-F Forward
Ta5d6ff - Ctrl-R Reload page
Ta5d6ff - Ctrl-U Open URL entry dialog
Ta5d6ff - Ctrl-S Save connected node
Ta5d6ff - Ctrl-G Toggle fullscreen browser window
Ta5d6ff - Ctrl-W Disconnect from node

Ta5d6ff>>>Announce Stream
Ta5d6ff - Ctrl-L Switch to Known Nodes list
Ta5d6ff - Ctrl-X Delete selected announce
Ta5d6ff - Ctrl-P Display peered LXMF Propagation Nodes

Ta5d6ff>>>Known Nodes
Ta5d6ff - Ctrl-L Switch to Announce Stream
Ta5d6ff - Ctrl-X Delete selected node entry
Ta5d6ff - Ctrl-P Display peered LXMF Propagation Nodes

Ta5d6ff>>>Peered LXMF Propagation Nodes
Ta5d6ff - Ctrl-L Switch to Announce Stream or Known Nodes
Ta5d6ff - Ctrl-X Break peering with selected node entry
Ta5d6ff - Ctrl-R Request immediate delivery sync of unhandled LXMs
Ta5d6ff'''

Te6edf3TOPIC_CONCEPTS Tff7b72= Ta5d6ff'''Ta5d6ff>Concepts and Terminology

Ta5d6ffThe following section will briefly introduce various concepts and terms used in the program.

Ta5d6ff>>Peer

Ta5d6ffA `*peer`* refers to another Nomad Network client, which will generally be operated by another person. But since Nomad Network is a general LXMF client, it could also be any other LXMF client, program, automated system or machine that can communicate over LXMF.

Ta5d6ffAll peers (and nodes) are identified by their `*address`* (which is, technically speaking, a Reticulum destination hash). An address consist of 32 hexadecimal characters (16 bytes), and looks like this:

Ta5d6ff`c<e9eafceea9e3664a5c55611c5e8c420a>
Ta5d6ff`l

Ta5d6ffAnyone can choose whatever display name they want, but addresses are always unique, and generated from the unique cryptographic keys of the peer. This is an important point to understand. Since there is not anyone controlling naming or address spaces in Nomad Network, you can easily come across another user with the same display name as you.

Ta5d6ffYour addresses will always be unique though, and you must always verify that the address you are communicating with is matching the address of the peer you expect to be in the other end.

Ta5d6ffTo make this easier, Nomad Network allows you to mark peers and nodes as either `*trusted`*, `*unknown`* or `*untrusted`*. In this way, you can mark the peers and nodes that you know to be legitimate, and easily spot peers with similar names as unrelated.

Ta5d6ff>>Announces

Ta5d6ffAn `*announce`* can be sent by any peer or node on the network, which will notify other peers of its existence, and contains the cryptographic keys that allows other peers to communicate with it.

Ta5d6ffIn the `![ Network ]`! section of the program, you can monitor announces on the network, initiate conversations with announced peers, and announce your own peer on the network. You can also connect to nodes on the network and browse information shared by them.

Ta5d6ff>>Conversations

Ta5d6ffNomad Network uses the term `*conversation`* to signify both direct peer-to-peer messaging threads, and also discussion threads with an arbitrary number of participants that might change over time.

Ta5d6ffBoth things like discussion forums and chat threads can be encapsulated as conversations in Nomad Network. The user interface will indicate the different characteristics a conversation can take, and also what form of transport encryption was used for messages within.

Ta5d6ffIn the `![ Conversations ]`! part of the program you can view and interact with all currently active conversations. You can also edit nickname and trust settings for peers belonging to these conversations here. To edit settings for a peer, select it in the conversation list, and press `!Ctrl-E`!.

Ta5d6ffBy default, Nomad Network will attempt to deliver messages to a peer directly. This happens by first establishing an encrypted link directly to the peer, and then delivering the message over it.

Ta5d6ffIf the desired peer is not available because it has disconnected from the network, this method will obviously fail. In this case, Nomad Network will attempt to deliver the message to a node, which will store and forward it over the network, for later retrieval by the destination peer. The message is encrypted before being transmitted to the network, and is only readable by the intended recipient.

Ta5d6ffFor propagated delivery to work, one or more nodes must be available on the network. If one or more trusted nodes are available, Nomad Network will automatically select the most suitable node to send the message via, but you can also manually specify what node to use.

Ta5d6ffTo select a node manually, go to the `![ Network ]`! part of the program, choose the desired node in the `*Known Nodes`* list, and select the `!< Info >`! button. In the `!Node Info`! dialog, you can specify the selected node as the default propagation node.

Ta5d6ffBy default, Nomad Network will check in with propagation nodes, and download any available messages every 6 hours. You can change this interval, or disable automatic syncronisation completely, by editing the configuration file.

Ta5d6ffYou can always initiate a sync manually, by pressing `!Ctrl-R`! in the `![ Conversations ]`! part of the program, which will open the syncronisation window.

Ta5d6ff>>Node

Ta5d6ffA Nomad Network `*node`* is an instance of the Nomad Network program that has been configured to host information for other peers and help propagate messages and information on the network.

Ta5d6ffNodes can host pages (similar to webpages) written in a markup-language called `*micron`*, as well as make files and other resources available for download for peers on the network. Nodes also form a distributed message store for offline users, and allows messages to be exchanged between peers that are not online at the same time.

Ta5d6ffIf no nodes exist on a network, all peers will still be able to communicate directly peer-to-peer, but both endpoints of a conversation will need to be available at the same time to converse. When nodes exist on the network, messages will be held and syncronised between nodes for deferred delivery if the destination peer is unavailable. Nodes will automatically discover and peer with each other, and handle syncronisation of message stores.

Ta5d6ffTo learn how to host your own node, read the `*Hosting a Node`* section of this guide.

Ta5d6ff'''

Te6edf3TOPIC_HOSTING Tff7b72= Ta5d6ff'''Ta5d6ff>Hosting a Node

Ta5d6ffTo host a node on the network, you must enable it in the configuration file, by setting the `*enable_node`* directive to `*yes`*. You should also configure the other node-related parameters such as the node name and announce interval settings. Once node hosting has been enabled in the configuration, Nomad Network will start hosting your node as soon as the program is launched, and other peers on the network will be able to connect and interact with content on your node.

Ta5d6ffBy default, no content is defined, apart from a short placeholder home page. To learn how to add your own content, read on.

Ta5d6ff>>Distributed Message Store

Ta5d6ffAll nodes on the network will automatically participate in a distributed message store that allows users to exchange messages, even when they are not connected to the network at the same time.

Ta5d6ffWhen Nomad Network is configured to host a node, by default it also configures itself as an LXMF Propagation Node, and automatically discovers and peers with other propagation nodes on the network. This process is completely automatic and requires no configuration from the node operator.

Ta5d6ff`!However`!, if there is already an abundance of Propagation Nodes on the network, or the operator simply wishes to host a pageserving-only node, Propagation Node hosting can be disabled in the configuration file.

Ta5d6ffTo view LXMF Propagation nodes that are currently peered with your node, go to the `![ Network ]`! part of the program and press `!Ctrl-P`!. In the list of peered Propagation Nodes, it is possible to:

Ta5d6ff - Immediately break peering with a node by pressing `!Ctrl-X`!
Ta5d6ff - Request an immediate delivery sync of all unhandled messages for a node, by pressing `!Ctrl-R`!

Ta5d6ffThe distributed message store is resilient to intermittency, and will remain functional as long as at least one node remains on the network. Nodes that were offline for a time will automatically be synced up to date when they regain connectivity.

Ta5d6ff>>Pages

Ta5d6ffNomad Network nodes can host pages similar to web pages, that other peers can read and interact with. Pages are written in a compact markup language called `*micron`*. To learn how to write formatted pages with micron, see the `*Markup`* section of this guide (which is, itself, written in micron). Pages can be linked together with hyperlinks, that can also link to pages (or other resources) on other nodes.

Ta5d6ffTo add pages to your node, place micron files in the `*pages`* directory of your Nomad Network programs `*storage`* directory. By default, the path to this will be `!~/.nomadnetwork/storage/pages`!. You should probably create the file `!index.mu`! first, as this is the page that will get served by default to a connecting peer.

Ta5d6ffYou can control how long a peer will cache your pages by including the cache header in a page. To do so, the first line of your page must start with `!#!c=X`!, where `!X`! is the cache time in seconds. To tell the peer to always load the page from your node, and never cache it, set the cache time to zero. You should only do this if there is a real need, for example if your page displays dynamic content that `*must`* be updated at every page view. The default caching time is 12 hours. In most cases, you should not need to include the cache control header in your pages.

Ta5d6ff>> Dynamic Pages

Ta5d6ffYou can use a preprocessor such as PHP, bash, Python (or whatever you prefer) to generate dynamic pages and fully interactive applications running over Nomad Network. To do so, just set executable permissions on the relevant page file, and be sure to include the interpreter at the beginning of the file, for example `!#!/usr/bin/python3`!.

Ta5d6ffData from fields and link variables will be passed to these scipts or programs as environment variables, and can simply be read by any method for accessing such.

Ta5d6ffIn the `!examples`! directory, you can find various small examples for the use of this feature. The currently included examples are:

Ta5d6ff - A messageboard that receives messages over LXMF, contributed by trippcheng
Ta5d6ff - A simple demonstration on how to create fields and read entered data in node-side scripts

Ta5d6ffBy default, you can find the examples in `!~/.nomadnetwork/examples`!. If you build something neat, that you feel would fit here, you are more than welcome to contribute it.

Ta5d6ff>>Authenticating Users

Ta5d6ffSometimes, you donTa5d6ff'Ta5d6fft want everyone to be able to view certain pages or execute certain scripts. In such cases, you can use `*authentication`* to control who gets to run certain requests.

Ta5d6ffTo enable authentication for any page, simply add a new file to your pages directory with Ta5d6ff"Ta5d6ff.allowedTa5d6ff"Ta5d6ff added to the file-name of the page. If your page is named Ta5d6ff"Ta5d6ffsecret_page.muTa5d6ff"Ta5d6ff, just add a file named Ta5d6ff"Ta5d6ffsecret_page.mu.allowedTa5d6ff"Ta5d6ff.

Ta5d6ffFor each user allowed to access the page, add a line to this file, containing the hash of that users primary identity. Users can find their own identity hash in the `![ Network ]`! part of the program, under `!Local Peer Info`!. If you want to allow access for three different users, your file would look like this:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffd454bcdac0e64fb68ba8e267543ae110
Ta5d6ff2b9ff3fb5902c9ca5ff97bdfb239ef50
Ta5d6ff7106d5abbc7208bfb171f2dd84b36490
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffYou can also dynamically generate this list, by making the file executable, and writing a script (in whatever language you want), that prints the list to stdout. Every time someone tries to request the page, Nomad Network will check the allowed identities list, and only grant access to allowed users.

Ta5d6ffBy default, Nomad Network connects anonymously to all nodes. To be able to identify, and access restricted pages, you must allow identifying on a per-node basis. To allow identifying when connecting to a node, you must go to the `!Known Nodes`! list in the `![ Network ]`! part of the program, and enable the `!Identify When Connecting`! checkbox under `!Node Info`!.

Ta5d6ff>>Files

Ta5d6ffLike pages, you can place files you want to make available in the `!~/.nomadnetwork/storage/files`! directory. To let a peer download a file, you should create a link to it in one of your pages.

Ta5d6ff>>Links and URLs

Ta5d6ffLinks to pages and resources in Nomad Network use a simple URL format. Here is an example:

Ta5d6ff`!18176ffddcc8cce1ddf8e3f72068f4a6:/page/index.mu`!

Ta5d6ffThe first part is the 10 byte destination address of the node (represented as readable hexadecimal), followed by the `!:`! character. Everything after the `!:`! represents the request path.

Ta5d6ffBy convention, Nomad Network nodes maps all hosted pages under the `!/page`! path, and all hosted files under the `!/file`! path. You can create as many subdirectories for pages and files as you please, and they will be automatically mapped to corresponding request paths.

Ta5d6ffYou can omit the destination address of the node, if you are reffering to a local page or file. You must still keep the `!:`! character. In such a case, the URL to a page could look like this:

Ta5d6ff`!:/page/other_page.mu`!

Ta5d6ffThe URL to a local file could look like this:

Ta5d6ff`!:/file/document.pdf`!

Ta5d6ffLinks can be inserted into micron documents. See the `*Markup`* section of this guide for info on how to do so.

Ta5d6ff'''

Te6edf3TOPIC_INTERFACES Tff7b72= Ta5d6ff'''Ta5d6ff>Interfaces

Ta5d6ffReticulum supports using many kinds of devices as networking interfaces, and allows you to mix and match them in any way you choose.

Ta5d6ffThe number of distinct network topologies you can create with Reticulum is more or less endless, but common to them all is that you will need to define one or more interfaces for Reticulum to use.

Ta5d6ffThe `![ Interfaces ]`! section of NomadNet lets you add, monitor, and update interfaces configured for your Reticulum instance.

Ta5d6ffIf you are starting NomadNet for the first time you will find that an `!AutoInterface`! has been added by default. This interface will try to use your available network device to communicate with other peers discovered on your local network.

Ta5d6ffInterfaces come in many different types and can interact with physical mediums like LoRa radios or standard IP networks.

Ta5d6ff>>Viewing Interfaces

Ta5d6ffTo view more info about an interface, navigate using the `!Up`! and `!Down`! arrow keys or by clicking with the mouse. Pressing `! < Enter >`! on a selected interface will bring you to a detailed interface view, which will show configuration parameters and realtime charts. From here you can also disable or edit the interface. To change the orientation of the TX/RX charts, press `!< V >`! for a vertical layout, and `!< H >`! for a horizontal view.

Ta5d6ff>>Updating Interfaces

Ta5d6ffTo edit an interface, select the interface and press `!< Ctrl + E >`!.

Ta5d6ffTo remove an interface, select the interface and press `!< Ctrl + X >`!. You can also perform both of these actions from the details view.

Ta5d6ff>>Adding Interfaces

Ta5d6ffTo add a new interface, press `!< Ctrl + A >`!. From here you can select which type of interface you want to add. Each unique interface type will have different configuration options.

Ta5d6ff`Ffff`! (!) Note:`! After adding or modifying interfaces, you will need to restart NomadNet or your Reticulum instance for changes to take effect.`f`b


Ta5d6ff>Interface Types

Ta5d6ff>>AutoInterface

Ta5d6ffThe Auto Interface enables communication with other discoverable Reticulum nodes over autoconfigured IPv6 and UDP. It does not need any functional IP infrastructure like routers or DHCP servers, but will require at least some sort of switching medium between peers (a wired switch, a hub, a WiFi access point or similar).

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffInterface Name

Ta5d6ffOptional Parameters:
Ta5d6ffDevices: Specific network devices to use
Ta5d6ffIgnored Devices: Network devices to exclude
Ta5d6ffGroup ID: Create isolated networks on the same physical LAN
Ta5d6ffDiscovery Scope: Can set to link, admin, site, organisation or global
Ta5d6ff```

Ta5d6ffThe AutoInterface is ideal for quickly connecting to other Reticulum nodes on your local network without complex configuration.

Ta5d6ff>>TCPClientInterface

Ta5d6ffThe TCP Client interface connects to remote TCP server interfaces, enabling communication over the Internet or private networks.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffTarget Host: Hostname or IP address of the server
Ta5d6ffTarget Port: Port number to connect to

Ta5d6ffOptional Parameters:
Ta5d6ffI2P Tunneled: Enable for connecting through I2P
Ta5d6ffKISS Framing: Enable for KISS framing for software modems
Ta5d6ff```

Ta5d6ffThis interface is commonly used to connect to Reticulum gateways or other persistent nodes on the Internet.

Ta5d6ff>>TCPServerInterface

Ta5d6ffThe TCP Server interface listens for incoming connections, allowing other Reticulum peers to connect to your node using TCPClientInterface.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffListen IP: IP address to bind to (0.0.0.0 for all interfaces)
Ta5d6ffListen Port: Port number to listen on

Ta5d6ffOptional Parameters:
Ta5d6ffPrefer IPv6: Bind to IPv6 address if available
Ta5d6ffI2P Tunneled: Enable for I2P tunnel support
Ta5d6ffDevice: Specific network device to use (e,g
Ta5d6ff```

Ta5d6ffUseful when you want other nodes to be able to connect to your Transport instance over TCP/IP.

Ta5d6ff>>UDPInterface

Ta5d6ffThe UDP interface allows communication over IP networks using UDP packets.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffListen IP: IP address to bind to
Ta5d6ffListen Port: Port to listen on
Ta5d6ffForward IP: IP address to forward to (Can be broadcast address)
Ta5d6ffForward Port: Port to forward to

Ta5d6ffOptional Parameters:
Ta5d6ffDevice: Specific network device to use
Ta5d6ff```

Ta5d6ff>>I2PInterface

Ta5d6ffThe I2P interface enables connections over the Invisible Internet Protocol. The I2PInterface requires an I2P daemon to be running on your system, such as `!i2pd`!

Ta5d6ff```
Ta5d6ffOptional Parameters:
Ta5d6ffPeers: I2P addresses to connect to (Can be left as none if running as a Transport)
Ta5d6ff```


Ta5d6ff>>RNodeInterface

Ta5d6ffThe RNode interface allows using LoRa transceivers running RNode firmware as Reticulum network interfaces.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffPort: Serial port or BLE device path
Ta5d6ffFrequency: Operating frequency in MHz
Ta5d6ffBandwidth: Channel bandwidth
Ta5d6ffTX Power: Transmit power in dBm
Ta5d6ffSpreading Factor: LoRa spreading factor (7-12)
Ta5d6ffCoding Rate: LoRa coding rate (4:5-4:8)

Ta5d6ffOptional Parameters:
Ta5d6ffID Callsign: Station identification
Ta5d6ffID Interval: Identification interval in seconds
Ta5d6ffAirtime Limits: Control duty cycle
Ta5d6ff```

Ta5d6ffThe interface includes a parameter calculator to estimate link budget, sensitivity, and data rate on the air based on your settings.

Ta5d6ff>>RNodeMultiInterface

Ta5d6ffThe RNode Multi Interface is designed for use with specific hardware platforms that support multiple subinterfaces or virtual radios. For most LoRa hardware platforms, you will want to use the standard `!RNodeInterface`! instead.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffPort: Serial port or BLE device path
Ta5d6ffSubinterfaces: Configuration for each subinterface / virtual radio port

Ta5d6ff```

Ta5d6ff>>SerialInterface

Ta5d6ffThe Serial interface enables using direct serial connections as Reticulum interfaces.

Ta5d6ff```
Ta5d6ffRequired Parameters:
Ta5d6ffPort: Serial port path
Ta5d6ffSpeed: Baud rate of serial device
Ta5d6ffDatabits: Number of data bits
Ta5d6ffParity: Parity setting
Ta5d6ffStopbits: Number of stop bits
Ta5d6ff```

Ta5d6ff>>KISSInterface

Ta5d6ffThe KISS interface supports packet radio modems and TNCs using the KISS protocol.

Ta5d6ff```
Ta5d6ffRequired Parameters:

Ta5d6ffPort: Serial port path
Ta5d6ffSpeed: Baud rate of serial device
Ta5d6ffDatabits: Number of data bits
Ta5d6ffParity: Parity setting
Ta5d6ffStopbits: Number of stop bits
Ta5d6ffPreamble: Modem preamble in milliseconds
Ta5d6ffTX Tail: Transmit tail in milliseconds
Ta5d6ffSlottime: CSMA slottime in milliseconds
Ta5d6ffPersistence: CSMA persistence value

Ta5d6ffOptional Parameters:

Ta5d6ffID Callsign: Station identification
Ta5d6ffID Interval: Identification interval in seconds
Ta5d6ffFlow Control: Enable packet flow control
Ta5d6ff```

Ta5d6ff>>PipeInterface

Ta5d6ffThe Pipe interface allows using external programs as Reticulum interfaces via stdin and stdout.

Ta5d6ff```
Ta5d6ffRequired Parameters:

Ta5d6ffCommand: External command to execute

Ta5d6ffOptional Parameters:
Ta5d6ffRespawn Delay: Seconds to wait before restarting after failure
Ta5d6ff```

Ta5d6ff<
Ta5d6ff>>
Ta5d6ff-∿
Ta5d6ff For more information and to view the full Interface documentation consult the Reticulum manual or visit https://reticulum.network/manual/interfaces.html (Requires external Internet connection)


Ta5d6ff>Interface Access Code (IFAC) Settings

Ta5d6ffInterface Access Codes create private networks and securely segment network traffic. Under `!Show more options`!, youTa5d6ff'Ta5d6ffll find these IFAC settings:

Ta5d6ff`!Virtual Network Name`! (network_name):
Ta5d6ffWhen added, creates a logical network that only communicates with other interfaces using the same name. This allows multiple separate Reticulum networks to exist on the same physical channel or medium.

Ta5d6ff`!IFAC Passphrase`! (passphrase):
Ta5d6ffSets an authentication passphrase for the interface. Only interfaces configured with the same passphrase will be able to communicate. Can be used with or without a network name.

Ta5d6ff`!IFAC Size`! (ifac_size):
Ta5d6ffControls the length of Interface Authentication Codes (8-512 bits). Larger sizes provide stronger security but add overhead to each packet. The default of `!8`! is usually appropriate for most uses.

Ta5d6ff>Interface Modes

Ta5d6ffWhen running a Transport node, you can configure interface modes that affect how Reticulum selects paths, propagates announces, and discovers routes:

Ta5d6ff`!full`!: Default mode with all discovery, meshing and transport functionality
Ta5d6ff`!gateway`!: Discovers paths on behalf of other nodes
Ta5d6ff`!access_point`!: Operates as a network access point
Ta5d6ff`!roaming`!: For physically mobile interfaces
Ta5d6ff`!boundary`!: For interfaces connecting different network segments

Ta5d6ff'''

Te6edf3TOPIC_CONVERSATIONS Tff7b72= Ta5d6ff'''Ta5d6ff>Conversations

Ta5d6ffConversations in Nomad Network
Ta5d6ff'''


Te6edf3TOPIC_CHANNELS Tff7b72= Ta5d6ff'''Ta5d6ff>Channels & RRC

Ta5d6ffNomadNet includes a built-in client for `*RRC`* (Reticulum Relay Chat), a real-time text chat protocol that runs over Reticulum. The reference RRC server implementation lives at https://github.com/kc1awv/rrcd. Each RRC server is called a `!hub`!, and each hub hosts one or more `!rooms`! (channels) you can join. Hubs are addressed by a Reticulum destination hash, just like nodes and conversations.

Ta5d6ffThe Channels section of NomadNet (accessible from the main menu, or by pressing the corresponding shortcut) is where you manage your hubs, view connection status, and chat in rooms.

Ta5d6ff>>Joining a hub

Ta5d6ffTo start chatting on a hub you must first add it to your hub list:

Ta5d6ff>>>
Ta5d6ff - Open the `![ Channels ]`! section.
Ta5d6ff - Press the shortcut to open the `*New Hub`* dialog (shown in the shortcut bar at the bottom).
Ta5d6ff - Enter the `!hub address`! (the destination hash of the hub, typically 16 hex characters / 8 bytes) and an optional display name.
Ta5d6ff - Confirm the dialog. The hub will appear in your hub list.
Ta5d6ff<

Ta5d6ffYou can sometimes receive a hub link from another user or from a node page. Activating such a link will pre-fill the New Hub dialog (and optionally a room name) for you.

Ta5d6ff>>Connecting and listing rooms

Ta5d6ffOnce a hub is added:

Ta5d6ff>>>
Ta5d6ff - Select the hub in the list and connect to it. Hubs can also be set to auto-reconnect.
Ta5d6ff - When connected, run `*/list`* to see public rooms hosted on this hub.
Ta5d6ff - Run `*/join <room>`* to join a room. Joined rooms appear under the hub in your channel list.
Ta5d6ff<

Ta5d6ff>>Chatting

Ta5d6ffInside a room, anything you type that does not start with a `*/`* is sent as a message to everyone in the room. The most common in-room commands are:

Ta5d6ff>>>
Ta5d6ff - `*/help`* show the full list of commands
Ta5d6ff - `*/who`* list users in the current room
Ta5d6ff - `*/nick <name>`* set your display name on this hub
Ta5d6ff - `*/topic <room> [text]`* view or set the room topic
Ta5d6ff - `*/part [room]`* leave a room (defaults to the current one)
Ta5d6ff - `*/quit`* disconnect from the hub
Ta5d6ff<

Ta5d6ffMessages support both `*markdown`* and `*micron`* formatting, depending on your render settings (see the `*Configuration Options`* topic). Because the backtick is the micron control character, you must use the `!broken-bar`! character `*¦`* in place of `*Tffea00\\Ta5d6ff``* when typing micron formatting in a message. The renderer converts `*¦`* back to `*Tffea00\\Ta5d6ff``* for display.

Ta5d6ff>>Mentions and privacy

Ta5d6ffYou will be notified (and the bell may ring, depending on your configuration) when another user mentions your nick with `*@yournick`*. RRC traffic is end-to-end encrypted by Reticulum between you and the hub, but other users in the same room can read what you write there. Treat rooms as semi-public spaces.

Ta5d6ff>>Hub etiquette

Ta5d6ffEach hub is operated independently and may have its own rules, MOTD, ban list and operator team. Be respecful, follow the hubTa5d6ff'Ta5d6ffs MOTD, and remember that operators can kick, ban and set modes on rooms they own.

Ta5d6ff'''


Te6edf3TOPIC_FIRST_RUN Tff7b72= Ta5d6ff'''Ta5d6ff>First Time Information

Ta5d6ffHi there. This first run message will only appear once. It contains a few pointers on getting started with Nomad Network, and getting the most out of the program.

Ta5d6ffYouTa5d6ff'Ta5d6ffre currently located in the guide section of the program. ITa5d6ff'Ta5d6ffm sorry I had to drag you here by force, but it will only happen this one time, I promise. If you ever get lost, return here and peruse the list of topics you see on the left. I will do my best to fill it with answers to mostly anything about Nomad Network.

Ta5d6ffTo get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color. If your terminal supports true-color, you can go to the `![ Config ]`! menu item, launch the editor and change the configuration.

Ta5d6ffIt is recommended to use a terminal size of at least 135x32. Nomad Network will work with smaller terminal sizes, but the interface might feel a bit cramped.

Ta5d6ffNerd Fonts and true-color are enabled by default. To get the full visual experience you should have a Nerd Font installed in your terminal. You can verify this by visiting the `*Display Test`* topic in this guide and checking the `!Nerd Font Rendering Test`! section. If those glyphs render correctly, you are good to go.

Ta5d6ffIf they do not render, install a Nerd Font and configure your terminal to use it. A few common approaches:

Ta5d6ff>>>
Ta5d6ff - `!Download from nerdfonts.com`!
Ta5d6ff Visit https://www.nerdfonts.com/font-downloads, pick a font you like
Ta5d6ff (Jet Brains Mono, Hack and Meslo are popular choices), unzip it
Ta5d6ff into `*~/.local/share/fonts`* (Linux) or install via Font Book (macOS),
Ta5d6ff then refresh the font cache with `*fc-cache -fv`* on Linux.

Ta5d6ff - `!Package manager`!
Ta5d6ff Many distros ship Nerd Font packages. On Arch: `*pacman -S ttf-nerd-fonts-symbols`*
Ta5d6ff or one of the per-family packages. On Debian/Ubuntu look for `*fonts-firacode`*
Ta5d6ff plus the symbols-only Nerd Font package, or install manually from the
Ta5d6ff nerdfonts.com release.

Ta5d6ff - `!Homebrew (macOS)`!
Ta5d6ff `*brew install --cask font-fira-code-nerd-font`* (or any other family).

Ta5d6ff - `!Configure your terminal`!
Ta5d6ff After installing, set your terminal emulatorTa5d6ff'Ta5d6ffs font to the Nerd Font
Ta5d6ff variant (it usually has Ta5d6ff"Ta5d6ffNerd FontTa5d6ff"Ta5d6ff in the name). Restart NomadNet
Ta5d6ff so the new font are picked up.
Ta5d6ff<

Ta5d6ffIf for some reason you cannot or do not want to use a Nerd Font, you can disable Nerd Font glyphs in the `![ Config ]`! menu and NomadNet will fall back to plain unicode symbols.

Ta5d6ffNomad Network expects that you are already connected to some form of Reticulum network. That could be as simple as the default one that Reticulum auto-generates on your local ethernet/WiFi network, or something much more complex. This short guide wonTa5d6ff'Ta5d6fft go into any details on building networks, but you will find other entries in the guide that deal with network setup and configuration.

Ta5d6ffAt least, if Nomad Network launches, it means that it is connected to a running Reticulum instance, that should in turn be connected to `*something`*, which should get you started.

Ta5d6ffFor more some more information, you can also read the `*Introduction`* section of this guide.

Ta5d6ffNow go out there and explore. This is still early days. See what you can find and create.

Ta5d6ff>>>>>>>>>>>>>>>
Ta5d6ff-Tffea00\u223f
Ta5d6ff<

Ta5d6ff'''

Te6edf3TOPIC_CONFIG Tff7b72= Ta5d6ff'''Ta5d6ff>Configuration Options

Ta5d6ffTo change the configuration of Nomad Network, you must edit the configuration file. If you did not manually specify a config path when you started the program, Nomad Net will look for a configuration in the folllowing directories:

Ta5d6ff `!/etc/nomadnetwork`!
Ta5d6ff `!~/.config/nomadnetwork`!
Ta5d6ff `!~/.nomadnetwork`!

Ta5d6ffIf no existing configuration file is found, one will be created at `!~/.nomadnetwork/config`! by default. The default configuration file contains comments on all the different configuration options present, and explains their possible settings.

Ta5d6ffYou can open the configuration file in any text-editor, and change the options. You can also use the editor built in to this program, under the `![ Config ]`! menu item. If the built-in editor does not gain focus, and your navigation keys are not working, try hitting enter or space, which should focus the editor and let you navigate the text.

Ta5d6ffFor reference, all the configuration options are listed and explained here as well. The configuration is divided into different sections, each with their own options.

Ta5d6ff>> Logging Section

Ta5d6ffThis section hold configuration directives related to logging output, and is delimited by the `![logging]`! header in the configuration file. Available directives, along with their default values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!loglevel = 4`!
Ta5d6ff>>>>
Ta5d6ffSets the verbosity of the log output. Must be an integer from 0 through 7.
Ta5d6ff>>>>>
Ta5d6ff0: Log only critical information
Ta5d6ff1: Log errors and lower log levels
Ta5d6ff2: Log warnings and lower log levels
Ta5d6ff3: Log notices and lower log levels
Ta5d6ff4: Log info and lower (this is the default)
Ta5d6ff5: Verbose logging
Ta5d6ff6: Debug logging
Ta5d6ff7: Extreme logging
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!destination = file`!
Ta5d6ff>>>>
Ta5d6ffDetermines the output destination of logged information. Must be `!file`! or `!console`!.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!logfile = ~/.nomadnetwork/logfile`!
Ta5d6ff>>>>
Ta5d6ffPath to the log file. Must be a writable filesystem path.
Ta5d6ff<

Ta5d6ff>> Client Section

Ta5d6ffThis section hold configuration directives related to the client behaviour and user interface of the program. It is delimited by the `![client]`! header in the configuration file. Available directives, along with their default values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!enable_client = yes`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether the client part of the program should be started on launch. Must be a boolean value.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!user_interface = text`!
Ta5d6ff>>>>
Ta5d6ffSelects which interface to use. Currently, only the `!text`! interface is available.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!downloads_path = ~/Downloads`!
Ta5d6ff>>>>
Ta5d6ffSets the filesystem path to store downloaded files in.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!notify_on_new_message = yes`!
Ta5d6ff>>>>
Ta5d6ffSets whether to output a notification character (bell or flash) to the terminal when a new message is received.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!announce_at_start = yes`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether your LXMF address is automatically announced when the program starts. Must be a boolean value.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!announce_interval = 360`!
Ta5d6ff>>>>
Ta5d6ffDetermines how often, in minutes, your LXMF address is announced on the network. Defaults to 6 hours.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!try_propagation_on_send_fail = yes`!
Ta5d6ff>>>>
Ta5d6ffWhen this option is enabled, and sending a message directly to a peer fails, Nomad Network will instead deliver the message to the propagation network, for later retrieval by the recipient.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!periodic_lxmf_sync = yes`!
Ta5d6ff>>>>
Ta5d6ffWhether the program should periodically download messages from available propagation nodes in the background.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!lxmf_sync_interval = 360`!
Ta5d6ff>>>>
Ta5d6ffThe number of minutes between each automatic sync. The default is equal to 6 hours.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!lxmf_sync_limit = 8`!
Ta5d6ff>>>>
Ta5d6ffOn low-bandwidth networks, it can be useful to limit the amount of messages downloaded in each sync. The default is 8. Set to 0 to download all available messages every time a sync occurs.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!required_stamp_cost = None`!
Ta5d6ff>>>>
Ta5d6ffYou can specify a required stamp cost for inbound messages to be accepted. Specifying a stamp cost will require untrusted senders that message you to include a cryptographic stamp in their messages. Performing this operation takes the sender an amount of time proportional to the stamp cost. As a rough estimate, a stamp cost of 8 will take less than a second to compute, and a stamp cost of 20 could take several minutes, even on a fast computer.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!accept_invalid_stamps = False`!
Ta5d6ff>>>>
Ta5d6ffYou can signal stamp requirements to senders, but still accept messages with invalid stamps by setting this option to True.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!max_accepted_size = 500`!
Ta5d6ff>>>>
Ta5d6ffThe maximum accepted unpacked size for messages received directly from other peers, specified in kilobytes. Messages larger than this will be rejected before the transfer begins.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!compact_announce_stream = yes`!
Ta5d6ff>>>>
Ta5d6ffWith this option enabled, Nomad Network will only display one entry in the announce stream per destination. Older announces are culled when a new one arrives.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!compose_in_markdown = yes`!
Ta5d6ff>>>>
Ta5d6ffConfigures whether sent messages are composed in markdown format.
Ta5d6ff<

Ta5d6ff>> RRC Section

Ta5d6ffThis section hold configuration directives related to the RRC client behaviour. It is delimited by the `![rrc]`! header in the configuration file. Available directives, along with their default values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!history_per_room_cap = 500`!
Ta5d6ff>>>>
Ta5d6ffMaximum number of messages retained per room in the in-memory scrollback buffer, and the number of messages restored from on-disk history at startup. The on-disk log itself is appended to indefinitely; this cap only controls how much backlog is visible. Set to 0 to keep every message in memory.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!filter_loaded_history = yes`!
Ta5d6ff>>>>
Ta5d6ffWhether to filter notices and system message when initially loading room history.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!ephemeral_notices = 10`!
Ta5d6ff>>>>
Ta5d6ffIf enabled, notices and system messages will disappear from the history after a while. 0 disables, otherwise sets the timeout in minutes.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!render_markdown = yes`!
Ta5d6ff>>>>
Ta5d6ffWhether or not to render markdown formatting in messages.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!render_micron = yes`!
Ta5d6ff>>>>
Ta5d6ffWhether or not to render micron formatting in messages. When using micron in messages, use the ¦ character in place of backticks.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!nick_colors = yes`!
Ta5d6ff>>>>
Ta5d6ffWhether or not to render RRC nicks in distinct colors based on identity hash.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!justify_msgs = yes`!
Ta5d6ff`!space_msgs = no`!
Ta5d6ff`!show_gutters = no`!
Ta5d6ff>>>>
Ta5d6ffRendering layout options for messages.
Ta5d6ff<

Ta5d6ff>> Text UI Section

Ta5d6ffThis section hold configuration directives related to the look and feel of the text-based user interface of the program. It is delimited by the `![textui]`! header in the configuration file. Available directives, along with their default values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!intro_time = 1`!
Ta5d6ff>>>>
Ta5d6ffNumber of seconds to display the intro screen. Set to 0 to disable the intro screen.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!intro_text = Nomad Network`!
Ta5d6ff>>>>
Ta5d6ffThe text to display on the intro screen.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!editor = editor`!
Ta5d6ff>>>>
Ta5d6ffWhat editor program to use when launching a text editor from within the program. Defaults to the `!editor`! alias, which in turn will use the default editor of the operating system.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!glyphs = unicode`!
Ta5d6ff>>>>
Ta5d6ffDetermines what set of glyphs the program uses for rendering the user interface.
Ta5d6ff>>>>>
Ta5d6ffThe `!plain`! set only uses ASCII characters, and should work on all terminals, but is rather boring.
Ta5d6ffThe `!unicode`! set uses more interesting glyphs and icons, and should work on most terminals. This is the default.
Ta5d6ffThe `!nerdfont`! set allows using a much wider range of glyphs, icons and graphics, and should be enabled if you are using a Nerd Font in your terminal.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!mouse_enabled = yes`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether the program should react to mouse/touch input. Must be a boolean value.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!sanitize_names = yes`!
Ta5d6ff>>>>
Ta5d6ffThis option allows sanitizing announced names before they are displayed in the user interface.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!hide_guide = no`!
Ta5d6ff>>>>
Ta5d6ffThis option allows hiding the `![ Guide ]`! section of the program.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!animation_interval = 1`!
Ta5d6ff>>>>
Ta5d6ffSets the animation refresh rate for certain animations and graphics in the program. Must be an integer.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!colormode = 256`!
Ta5d6ff>>>>
Ta5d6ffTells the program what color palette is supported by the terminal. Most terminals support `!256`! colors. If your terminal supports full-color / RGB-mode, set to `!24bit`!. Available options:
Ta5d6ff>>>>>
Ta5d6ff`!monochrome`! Single-color (black/white) palette, for monochrome displays
Ta5d6ff`!16`! Low-color mode for really old-school terminals
Ta5d6ff`!88`! Standard palletised color-mode for terminals
Ta5d6ff`!256`! Almost all modern terminals support this mode
Ta5d6ff`!24bit`! Most new terminals support this full-color mode
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!theme = dark`!
Ta5d6ff>>>>
Ta5d6ffWhat color theme to use. Set it to match your terminal theme. Can be either `!dark`! or `!light`!.
Ta5d6ff<

Ta5d6ff>> Node Section

Ta5d6ffThis section holds configuration directives related to the node hosting. It is delimited by the `![node]`! header in the configuration file. Available directives, along with example values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!enable_node = no`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether the node server should be started on launch. Must be a boolean value, and is turned off by default.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!node_name = DisplayNameTa5d6ff'Ta5d6ffs Node`!
Ta5d6ff>>>>
Ta5d6ffDefines what the announced name of the node should be.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!announce_at_start = yes`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether your node is automatically announced on the network when the program starts. Must be a boolean value.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!announce_interval = 360`!
Ta5d6ff>>>>
Ta5d6ffDetermines how often, in minutes, your node is announced on the network. Defaults to 6 hours.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!pages_path = ~/.nomadnetwork/storage/pages`!
Ta5d6ff>>>>
Ta5d6ffDetermines where the node server will look for hosted pages. Must be a readable filesystem path.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!page_refresh_interval = 0`!
Ta5d6ff>>>>
Ta5d6ffDetermines the interval in minutes for rescanning the hosted pages path. By default, this option is disabled, and the pages path will only be scanned on startup.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!files_path = ~/.nomadnetwork/storage/files`!
Ta5d6ff>>>>
Ta5d6ffDetermines where the node server will look for downloadable files. Must be a readable filesystem path.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!file_refresh_interval = 0`!
Ta5d6ff>>>>
Ta5d6ffDetermines the interval in minutes for rescanning the hosted files path. By default, this option is disabled, and the files path will only be scanned on startup.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!disable_propagation = yes`!
Ta5d6ff>>>>
Ta5d6ffWhen Nomad Network is hosting a node, it can also run an LXMF propagation node. If there is already a large amount of propagation nodes on the network, or you simply want to run a pageserving-only node, you can disable running a propagation node.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!message_storage_limit = 2000`!
Ta5d6ff>>>>
Ta5d6ffConfigures the maximum amount of storage, in megabytes, that the LXMF Propagation Node will use to store messages.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!max_transfer_size = 256`!
Ta5d6ff>>>>
Ta5d6ffThe maximum accepted transfer size per incoming propagation transfer, in kilobytes. This also sets the upper limit for the size of single messages accepted onto this propagation node. If a node wants to propagate a larger number of messages to this node, than what can fit within this limit, it will prioritise sending the smallest, newest messages first, and try with any remaining messages at a later point.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf`!
Ta5d6ff>>>>
Ta5d6ffConfigures the LXMF Propagation Node to prioritise storing messages for certain destinations. If the message store reaches the specified limit, LXMF will prioritise keeping messages for destinations specified with this option. This setting is optional, and generally you do not need to use it.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!max_peers = 25`!
Ta5d6ff>>>>
Ta5d6ffConfigures the maximum number of other nodes the LXMF Propagation Node will automatically peer with. The default is 50, but can be lowered or increased according to available resources.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!static_peers = e17f833c4ddf8890dd3a79a6fea8161d, 5a2d0029b6e5ec87020abaea0d746da4`!
Ta5d6ff>>>>
Ta5d6ffConfigures the LXMF Propagation Node to always maintain propagation node peering with the specified list of destination hashes.
Ta5d6ff<

Ta5d6ff>> Printing Section

Ta5d6ffThis section holds configuration directives related to printing. It is delimited by the `![printing]`! header in the configuration file. Available directives, along with example values, are as follows:

Ta5d6ff>>>
Ta5d6ff`!print_messages = no`!
Ta5d6ff>>>>
Ta5d6ffDetermines whether messages should be printed upon arrival. Must be a boolean value, and is turned off by default.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!message_template = ~/.nomadnetwork/print_template_msg.txt`!
Ta5d6ff>>>>
Ta5d6ffDetermines where the template for printed messages is found. Must be a filesystem path. If you set this path to a non-existing file, an example will be generated in the specified location.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!print_from = 76fe5751a56067d1e84eef3e88eab85b, trusted`!
Ta5d6ff>>>>
Ta5d6ffDetermines from which destinations messages are printed. Can be a list of destinations hashes, the keyword Ta5d6ff"Ta5d6fftrustedTa5d6ff"Ta5d6ff, or Ta5d6ff"Ta5d6ffeverywhereTa5d6ff"Ta5d6ff.
Ta5d6ff<

Ta5d6ff>>>
Ta5d6ff`!print_command = lp -d PRINTER_NAME -o cpi=16 -o lpi=8`!
Ta5d6ff>>>>
Ta5d6ffSpecifies the command that Nomad Network uses to print the message. Defaults to Ta5d6ff"Ta5d6fflpTa5d6ff"Ta5d6ff. The above example works well for small thermal-roll printers.
Ta5d6ff<

Ta5d6ff>Ignoring Destinations

Ta5d6ffIf you encounter peers or nodes on the network, that you would rather not see in your client, you can add them to the `!~/.nomadnetwork/ignored`! file. To ignore nodes or peers, add one 32-character hexadecimal destination hash per line to the file. To unignore one again, simply remove the corresponding entry from the file and restart Nomad Network.
Ta5d6ff'''

Te6edf3TOPIC_NETWORKS Tff7b72= Ta5d6ff'''Ta5d6ff>Network Configuration

Ta5d6ffNomad Network uses the Reticulum Network Stack for communication and encryption. This means that it will use any interfaces and communications channels already defined in your Reticulum configuration.

Ta5d6ffReticulum supports using many kinds of devices as networking interfaces, and allows you to mix and match them in any way you choose. The number of distinct network topologies you can create with Reticulum is more or less endless, but common to them all is that you will need to define one or more interfaces for Reticulum to use.

Ta5d6ffIf you have not changed the default Reticulum configuration, which should be located at `!~/.reticulum/config`!, you will have one interface active right now. With it, you should be able to communicate with any other peers and systems that exist on your local ethernet or WiFi network, if your computer is connected to one, and most probably nothing else outside of that.

Ta5d6ffTo learn how to configure your Reticulum setup to use LoRa radios, packet radio or other interfaces, or connect to other Reticulum networks via the Internet, the best places to start is to read the relevant parts of the Reticulum Manual, which can be found on GitHub:

Ta5d6ff`c`_https://markqvist.github.io/Reticulum/manual/interfaces.html`_
Ta5d6ff`l

Ta5d6ffIf you donTa5d6ff'Ta5d6fft currently have access to the Internet, you can generate a configuration file full of examples of all the supported interface types, by using the command `!rnsd --exampleconfig`!. Using those examples, it should be possible to get a working setup going.

Ta5d6ffFor future reference, you can download the Reticulum Manual in PDF format here:

Ta5d6ff`c`_https://github.com/markqvist/Reticulum/raw/master/docs/ReticulumTa5d6ff%Ta5d6ff20Manual.pdf`_
Ta5d6ff`l

Ta5d6ffIt might be nice to keep that handy when you are not connected to the Internet, as it is full of information and examples that are also very relevant to Nomad Network.

Ta5d6ff>The Distributed Backbone

Ta5d6ffIf you have Internet access, and just want to get started experimenting, you can connected to the distributed global Reticulum backbone. For more information about this, see the Reticulum Manual, or sites such as https://directory.rns.recips or https://rmap.world.

Ta5d6ffIf you connect to the public backbone, you can leave nomadnet running for a while and wait for it to receive announces from other nodes on the network that host pages or services, or you can try connecting directly to some nodes listed here:

Ta5d6ffTo browse pages on a node that is not currently known, open the URL dialog in the `![ Network ]`! section of the program by pressing `!Ctrl+U`!, paste or enter the address and select `!< Go >`! or press enter. Nomadnet will attempt to discover and connect to the requested node. You can save the currently connected node by pressing `!Ctrl+S`!.
Ta5d6ff'''

Te6edf3TOPIC_DISPLAYTEST Tff7b72= Ta5d6ff'''Ta5d6ff>Markup & Color Display Test


Ta5d6ff`cYou can use this section to gauge how well your terminal reproduces the various types of formatting used by Nomad Network.
Ta5d6ff``


Ta5d6ff>>>>>>>>>>>>>>>>>>>>
Ta5d6ff-Tffea00\u223f
Ta5d6ff<


Ta5d6ff>>
Ta5d6ff`a`!This line should be bold, and aligned to the left`!

Ta5d6ff`c`*This one should be italic and centered`*

Ta5d6ff`r`_And this one should be underlined, aligned right`_
Ta5d6ff``

Ta5d6ffThe following line should contain a red gradient bar:
Ta5d6ff`B100 `B200 `B300 `B400 `B500 `B600 `B700 `B800 `B900 `Ba00 `Bb00 `Bc00 `Bd00 `Be00 `Bf00`b

Ta5d6ffThe following line should contain a green gradient bar:
Ta5d6ff`B010 `B020 `B030 `B040 `B050 `B060 `B070 `B080 `B090 `B0a0 `B0b0 `B0c0 `B0d0 `B0e0 `B0f0`b

Ta5d6ffThe following line should contain a blue gradient bar:
Ta5d6ff`B001 `B002 `B003 `B004 `B005 `B006 `B007 `B008 `B009 `B00a `B00b `B00c `B00d `B00e `B00f`b

Ta5d6ffThe following line should contain a grayscale gradient bar:
Ta5d6ff`Bg06 `Bg13 `Bg20 `Bg26 `Bg33 `Bg40 `Bg46 `Bg53 `Bg59 `Bg66 `Bg73 `Bg79 `Bg86 `Bg92 `Bg99`b

Ta5d6ffUnicode Glyphs : Tffea00\u2713Ta5d6ff Tffea00\u2715Ta5d6ff Tffea00\u26a0Ta5d6ff Tffea00\u24c3Ta5d6ff Tffea00\u2193

Ta5d6ffNerd Font Glyphs : Tffea00\uf484Ta5d6ff Tffea00\U000f04c5Ta5d6ff Tffea00\U000f0219Ta5d6ff Tffea00\U000f0002Ta5d6ff Tffea00\uf415Ta5d6ff Tffea00\uf023Ta5d6ff Tffea00\uf06e


Ta5d6ff>>Nerd Font Rendering Test

Ta5d6ff`cSince Nerd Font glyphs and true-color are enabled by default, the rows below should render as crisp icons rather than empty squares, question marks, or fallback ASCII. If any glyph appears blank or boxed, your terminal is not using a Nerd Font, or the font is missing the required glyph range.
Ta5d6ff``

Ta5d6ff>>>
Ta5d6ffCommon UI icons : Tffea00\uf484Ta5d6ff Tffea00\uf415Ta5d6ff Tffea00\uf023Ta5d6ff Tffea00\uf06eTa5d6ff Tffea00\uf055Ta5d6ff Tffea00\uf056Ta5d6ff Tffea00\uf059
Ta5d6ffStatus / state : Tffea00\U000f04c5Ta5d6ff Tffea00\U000f0219Ta5d6ff Tffea00\U000f0002Ta5d6ff Tffea00\U000f1397Ta5d6ff Tffea00\U000f12fcTa5d6ff Tffea00\U000f0156
Ta5d6ffNetwork / radio : Tffea00\U000f05a9Ta5d6ff Tffea00\U000f05aaTa5d6ff Tffea00\U000f05abTa5d6ff Tffea00\U000f05acTa5d6ff Tffea00\uf1ebTa5d6ff Tffea00\uf012
Ta5d6ffPeople / messaging: Tffea00\uf0c0Ta5d6ff Tffea00\uf007Ta5d6ff Tffea00\uf2bdTa5d6ff Tffea00\uf0e0Ta5d6ff Tffea00\uf27aTa5d6ff Tffea00\uf086
Ta5d6ffDevices / files : Tffea00\uf233Ta5d6ff Tffea00\uf07bTa5d6ff Tffea00\uf15bTa5d6ff Tffea00\uf019Ta5d6ff Tffea00\uf093Ta5d6ff Tffea00\uf1c0
Ta5d6ff<

Ta5d6ff`cIf the above renders correctly, you have a working Nerd Font setup and can leave the defaults as-is. If not, see the `*First Time Information`* topic for install instructions.
Ta5d6ff``
Ta5d6ff'''


Te6edf3TOPIC_LICENSES Tff7b72= Ta5d6ff'''Ta5d6ff>Thanks, Acknowledgements and Licenses

Ta5d6ffThis program uses various other software components, without which Nomad Network would not have been possible. Sincere thanks to the authors and contributors of the following projects

Ta5d6ff>>>
Ta5d6ff - `!Cryptography.io`! by `*pyca`*
Ta5d6ff https://cryptography.io/
Ta5d6ff BSD License

Ta5d6ff - `!Urwid`! by `*Ian Ward`*
Ta5d6ff http://urwid.org/
Ta5d6ff LGPL-2.1 License

Ta5d6ff - `!Additional Urwid Widgets`! by `*AFoeee`*
Ta5d6ff https://github.com/AFoeee/additional_urwid_widgets
Ta5d6ff MIT License

Ta5d6ff - `!Scrollable`! by `*rndusr`*
Ta5d6ff https://github.com/rndusr/stig/blob/master/stig/tui/scroll.py
Ta5d6ff GPLv3 License

Ta5d6ff - `!Configobj`! by `*Michael Foord`*
Ta5d6ff https://github.com/DiffSK/configobj
Ta5d6ff BSD License

Ta5d6ff - `!Reticulum Network Stack`! by `*unsignedmark`*
Ta5d6ff https://github.com/markqvist/Reticulum
Ta5d6ff MIT License

Ta5d6ff - `!LXMF`! by `*unsignedmark`*
Ta5d6ff https://github.com/markqvist/LXMF
Ta5d6ff MIT License
Ta5d6ff'''


Te6edf3TOPIC_MARKUP Tff7b72= Ta5d6ff'''Ta5d6ff>Outputting Formatted Text


Ta5d6ff>>>>>>>>>>>>>>>
Ta5d6ff-Tffea00\u223f
Ta5d6ff<

Ta5d6ff`c`!Hello!`! This is output from `*micron`*
Ta5d6ffMicron generates formatted text for your terminal
Ta5d6ff`a

Ta5d6ff>>>>>>>>>>>>>>>
Ta5d6ff-Tffea00\u223f
Ta5d6ff<


Ta5d6ffNomad Network supports a simple and functional markup language called `*micron`*. If you are familiar with `*markdown`* or `*HTML`*, you will feel right at home writing pages with micron.

Ta5d6ffWith micron you can easily create structured documents and pages with formatting, colors, glyphs and icons, ideal for display in terminals.

Ta5d6ff>Table of Contents

Ta5d6ff `F79d`_`[A Few Demo Outputs`#a-few-demo-outputs]`_`f
Ta5d6ff `F79d`_`[Micron Tags`#micron-tags]`_`f
Ta5d6ff `F79d`_`[High Level Stuff`#high-level-stuff]`_`f
Ta5d6ff `F79d`_`[Colors`#colors]`_`f
Ta5d6ff `F79d`_`[Page Foreground and Background Colors`#page-foreground-and-background-colors]`_`f
Ta5d6ff `F79d`_`[Links`#links]`_`f
Ta5d6ff `F79d`_`[Anchors`#anchors]`_`f
Ta5d6ff `F79d`_`[Tables`#tables]`_`f
Ta5d6ff `F79d`_`[Fields & Requests`#fields-requests]`_`f
Ta5d6ff `F79d`_`[Comments`#comments]`_`f
Ta5d6ff `F79d`_`[Partials`#partials]`_`f
Ta5d6ff `F79d`_`[Literals`#literals]`_`f
Ta5d6ff `F79d`_`[Closing Remarks`#closing-remarks]`_`f

Ta5d6ff>>Recommendations and Requirements

Ta5d6ffWhile micron can output formatted text to even the most basic terminal, thereTa5d6ff'Ta5d6ffs a few capabilities your terminal `*must`* support to display micron output correctly, and some that, while not strictly necessary, make the experience a lot better.

Ta5d6ffFormatting such as `_underline`_, `!bold`! or `*italics`* will be displayed if your terminal supports it.

Ta5d6ffIf you are having trouble getting micron output to display correctly, try using `*gnome-terminal`* or `*alacritty`*, which should work with all formatting options out of the box. Most other terminals will work fine as well, but you might have to change some settings to get certain formatting to display correctly.

Ta5d6ff>>>Encoding

Ta5d6ffAll micron sources are intepreted as UTF-8, and micron assumes it can output UTF-8 characters to the terminal. If your terminal does not support UTF-8, output will be faulty.

Ta5d6ff>>>Colors

Ta5d6ffShading and coloring text and backgrounds is integral to micron output, and while micron will attempt to gracefully degrade output even to 1-bit terminals, you will get the best output with terminals supporting at least 256 colors. True-color support is recommended.

Ta5d6ff>>>Terminal Font

Ta5d6ffWhile any unicode capable font can be used with micron, itTa5d6ff'Ta5d6ffs highly recommended to use a `*Ta5d6ff"Ta5d6ffNerd FontTa5d6ff"Ta5d6ff`* (see https://www.nerdfonts.com/), which will add a lot of extra glyphs and icons to your output.

Ta5d6ff> A Few Demo Outputs

Ta5d6ff`F222`Bddd

Ta5d6ff`cWith micron, you can control layout and presentation
Ta5d6ff`a

Ta5d6ff``

Ta5d6ff`B33f

Ta5d6ffYou can change background ...

Ta5d6ff``

Ta5d6ff`B393

Ta5d6ff`r`F320... and foreground colors`f
Ta5d6ff`a

Ta5d6ff`b

Ta5d6ffIf you want to make a break, horizontal dividers can be inserted. They can be plain, like the one below this text, or you can style them with unicode characters and glyphs, like the wavy divider in the beginning of this document.

Ta5d6ff-

Ta5d6ff`cText can be `_underlined`_, `!bold`! or `*italic`*.

Ta5d6ffYou can also `_`*`!`B5d5`F222combine`f`b`_ `_`Ff00f`Ff80o`Ffd0r`F9f0m`F0f2a`F0fdt`F07ft`F43fi`F70fn`Fe0fg`` for some fabulous effects.
Ta5d6ff`a


Ta5d6ff>>>Sections and Headings

Ta5d6ffYou can define an arbitrary number of sections and sub sections, each with their own named headings. Text inside sections will be automatically indented.

Ta5d6ff-

Ta5d6ffIf you place a divider inside a section, it will adhere to the section indents.

Ta5d6ff>>>>>
Ta5d6ffIf no heading text is defined, the section will appear as a sub-section without a header. This can be useful for creating indented blocks of text, like this one.

Ta5d6ff>Micron tags

Ta5d6ffTags are used to format text with micron. Some tags can appear anywhere in text, and some must appear at the beginning of a line. If you need to write text that contains a sequence that would be interpreted as a tag, you can escape it with the character Tffea00\\Ta5d6ff.

Ta5d6ffIn the following sections, the different tags will be introduced. Any styling set within micron can be reset to the default style by using the special Tffea00\\Ta5d6ff`Tffea00\\Ta5d6ff` tag anywhere in the markup, which will immediately remove any formatting previously specified.

Ta5d6ff>>Alignment

Ta5d6ffTo control text alignment use the tag Tffea00\\Ta5d6ff`c to center text, Tffea00\\Ta5d6ff`l to left-align, Tffea00\\Ta5d6ff`r to right-align, and Tffea00\\Ta5d6ff`a to return to the default alignment of the document. Alignment tags must appear at the beginning of a line. Here is an example:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`cThis line will be centered.
Ta5d6ffSo will this.
Ta5d6ff`aThe alignment has now been returned to default.
Ta5d6ff`rThis will be aligned to the right
Ta5d6ff``
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ff`cThis line will be centered.
Ta5d6ffSo will this.

Ta5d6ff`aThe alignment has now been returned to default.

Ta5d6ff`rThis will be aligned to the right

Ta5d6ff``


Ta5d6ff>>Formatting

Ta5d6ffText can be formatted as `!bold`! by using the Tffea00\\Ta5d6ff`! tag, `_underline`_ by using the Tffea00\\Ta5d6ff`_ tag and `*italic`* by using the Tffea00\\Ta5d6ff`* tag.

Ta5d6ffHereTa5d6ff'Ta5d6ffs an example of formatting text:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffWe shall soon see `!bold`! paragraphs of text decorated with `_underlines`_ and `*italics`*. Some even dare `!`*`_combine`` them!
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ffWe shall soon see `!bold`! paragraphs of text decorated with `_underlines`_ and `*italics`*. Some even dare `!`*`_combine`!`*`_ them!

Ta5d6ff``


Ta5d6ff>>Sections

Ta5d6ffTo create sections and subsections, use the > tag. This tag must be placed at the beginning of a line. To specify a sub-section of any level, use any number of > tags. If text is placed after a > tag, it will be used as a heading.

Ta5d6ffHere is an example of sections:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff>High Level Stuff
Ta5d6ffThis is a section. It contains this text.

Ta5d6ff>>Another Level
Ta5d6ffThis is a sub section.

Ta5d6ff>>>Going deeper
Ta5d6ffA sub sub section. We could continue, but you get the point.

Ta5d6ff>>>>
Ta5d6ffWait! ItTa5d6ff'Ta5d6ffs worth noting that we can also create sections without headings. They look like this.
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333
Ta5d6ff>High Level Stuff
Ta5d6ffThis is a section. It contains this text.

Ta5d6ff>>Another Level
Ta5d6ffThis is a sub section.

Ta5d6ff>>>Going deeper
Ta5d6ffA sub sub section. We could continue, but you get the point.

Ta5d6ff>>>>
Ta5d6ffWait! ItTa5d6ff'Ta5d6ffs worth noting that we can also create sections without headings. They look like this.
Ta5d6ff``


Ta5d6ff>Colors

Ta5d6ffForeground colors can be specified with the Tffea00\\Ta5d6ff`F tag, followed by three hexadecimal characters. To return to the default foreground color, use the Tffea00\\Ta5d6ff`f tag. Background color is specified in the same way, but by using the Tffea00\\Ta5d6ff`B and Tffea00\\Ta5d6ff`b tags.

Ta5d6ffHereTa5d6ff'Ta5d6ffs a few examples:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffYou can use `B5d5`F222 color `f`b `Ff00f`Ff80o`Ffd0r`F9f0m`F0f2a`F0fdt`F07ft`F43fi`F70fn`Fe0fg`f for some fabulous effects.
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ffYou can use `B5d5`F222 color `f`B333 `Ff00f`Ff80o`Ffd0r`F9f0m`F0f2a`F0fdt`F07ft`F43fi`F70fn`Fe0fg`f for some fabulous effects.

Ta5d6ff``

Ta5d6ff>Page Foreground and Background Colors

Ta5d6ffTo specify a background color for the entire page, place the `!#!bg=X`! header on one of the first lines of your page, where `!X`! is the color you want to use, for example `!444`!. If youTa5d6ff'Ta5d6ffre also using the cache control header, the background specifier must come `*after`* the cache control header. Likewise, you can specify the default text color by using the `!#!fg=X`! header.

Ta5d6ff>Links

Ta5d6ffLinks to pages, files or other resources can be created with the Tffea00\\Ta5d6ff`[ tag, which should always be terminated with a closing ]. You can create links with and without labels, it is up to you to control the formatting of links with other tags. Although not strictly necessary, it is good practice to at least format links with underlining.

Ta5d6ffHereTa5d6ff'Ta5d6ffs a few examples:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffHere is a link without any label: `[72914442a3689add83a09a767963f57c:/page/index.mu]

Ta5d6ffThis is a `[labeled link`72914442a3689add83a09a767963f57c:/page/index.mu] to the same page, but itTa5d6ff'Ta5d6ffs hard to see if you donTa5d6ff'Ta5d6fft know it

Ta5d6ffHere is `F00a`_`[a more visible link`72914442a3689add83a09a767963f57c:/page/index.mu]`_`f
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ffHere is a link without any label: `[72914442a3689add83a09a767963f57c:/page/index.mu]

Ta5d6ffThis is a `[labeled link`72914442a3689add83a09a767963f57c:/page/index.mu] to the same page, but itTa5d6ff'Ta5d6ffs hard to see if you donTa5d6ff'Ta5d6fft know it

Ta5d6ffHere is `F00f`_`[a more visible link`72914442a3689add83a09a767963f57c:/page/index.mu]`_`f

Ta5d6ff``

Ta5d6ffWhen links like these are displayed in the built-in browser, clicking on them or activating them using the keyboard will cause the browser to load the specified URL.

Ta5d6ff>Anchors

Ta5d6ffAnchors let you create jump points within a single page similar to anchors in HTML. You declare a position in the page with a name, then link to it from anywhere on the same page.

Ta5d6ff>>Auto-anchors from headers

Ta5d6ffEvery section heading you write also becomes an anchor automatically. The anchor name is the heading text after `*slugifying`*: lowercased, with any run of non-alphanumeric characters replaced by a single hyphen, and leading or trailing hyphens stripped. So `*>Hello World`* becomes the anchor `*hello-world`*, and `*>Introduction & Setup`* becomes `*introduction-setup`*.

Ta5d6ff>>Explicit anchors

Ta5d6ffIf you want an anchor, that isnTa5d6ff'Ta5d6fft tied to a heading, place one anywhere in your text with the Tffea00\\Ta5d6ff`: tag, followed by a name. Names may contain the characters `*A-Z`*, `*a-z`*, `*0-9`*, `*_`* and `*-`*, and end at any other character (a space, a newline, or punctuation).

Ta5d6ffThe anchor itself takes up no space and does not render. IsTa5d6ff'Ta5d6ffs just a position marker. An explicit anchor declared on an otherwise empty line binds to that lineTa5d6ff'Ta5d6ffs position.

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`:install-notes
Ta5d6ffSome installation notes for the user.

Ta5d6ffYou can also drop one mid-line. Example: see `:tip-3 ⚠ tip 3 below for caveats.
Ta5d6ff`=
Ta5d6ff``

Ta5d6ff>>Linking to an anchor

Ta5d6ffReuse the standard link syntax, with a `*#`*-prefixed URL:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Jump to Install Notes`#install-notes]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffWhen the user activates the link the browser scrolls the current page to the anchorTa5d6ff'Ta5d6ffs row.

Ta5d6ff>>Jumping to the next section

Ta5d6ffIf the URL is just `*#`* with no name after it, the link jumps to the next Tffea00\\Ta5d6ff`> header that appears after the linkTa5d6ff'Ta5d6ffs own position in the document. This is convenient for Ta5d6ff"Ta5d6ffContinue ↓Ta5d6ff"Ta5d6ff buttons after a long paragraph, without having to name every section:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Continue`#]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ff>>Anchors in external links

Ta5d6ffIf you want to link to an anchor on another page, you can include it as a request variable:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Conclusion`a8d24177d946de4f1f0a0fe1af9a1338:/page/document.mu`anchor=conclusion]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ff>>Notes on namespaces and collisions

Ta5d6ffAuto-anchors from headings and explicit Tffea00\\Ta5d6ff`: anchors share a single namespace per page. If an explicit anchor collides with a heading slug, the first one declared is where it will jump to.

Ta5d6ff>Tables

Ta5d6ffYou can include rendered tables by enclosing them in Tffea00\\Ta5d6ff`t tags. Optionally, you can also specify alignment and max rendering width by adding these properties to the opening Tffea00\\Ta5d6ff`t tag, like Tffea00\\Ta5d6ff`tc30. HereTa5d6ff'Ta5d6ffs an example:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`t
Ta5d6ff| Name | Price | Qty |
Ta5d6ff| ---- | :---: | --: |
Ta5d6ff| `F3a3Apple`f | Free | `!5`! |
Ta5d6ff| Orange | Ask, nicely | 3 |
Ta5d6ff`t
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following table:

Ta5d6ff`t
Ta5d6ff| Name | Price | Qty |
Ta5d6ff| ---- | :---: | --: |
Ta5d6ff| `F3a3Apple`f | Free | `!5`! |
Ta5d6ff| Orange | Ask, nicely | 3 |
Ta5d6ff`t

Ta5d6ff>Fields & Requests

Ta5d6ffNomad Network letTa5d6ff'Ta5d6ffs you use simple input fields for submitting data to node-side applications. Submitted data, along with other session variables will be available to the node-side script / program as environment variables.

Ta5d6ff>>Request Links

Ta5d6ffLinks can contain request variables and a list of fields to submit to the node-side application. You can include all fields on the page, only specific ones, and any number of request variables. To simply submit all fields on a page to a specified node-side page, create a link like this:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Submit Fields`:/page/fields.mu`*]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffNote the `!*`! following the extra `!Tffea00\\Ta5d6ff``! at the end of the path. This `!*`! denotes `*all fields`*. You can also specify a list of fields to include:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Submit Fields`:/page/fields.mu`username|auth_token]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffIf you want to include pre-set variables, you can do it like this:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`[Query the System`:/page/fields.mu`username|auth_token|action=view|amount=64]
Ta5d6ff`=
Ta5d6ff``

Ta5d6ff>> Fields

Ta5d6ffHereTa5d6ff'Ta5d6ffs an example of creating a field. WeTa5d6ff'Ta5d6ffll create a field named `!user_input`! and fill it with the text `!Pre-defined data`!. Note that we are using background color tags to make the field more visible to the user:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffA simple input field: `B444`<user_input`Pre-defined data>`b
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffYou must always set a field `*name`*, but you can of course omit the pre-defined value of the field:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffAn empty input field: `B444`<demo_empty`>`b
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffYou can set the size of the field like this:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffA sized input field: `B444`<16|with_size`>`b
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffIt is possible to mask fields, for example for use with passwords and similar:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffA masked input field: `B444`<!|masked_demo`hidden text>`b
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffAnd you can of course control all parameters at the same time:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffFull control: `B444`<!32|all_options`hidden text>`b
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffCollecting the above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ffA simple input field: `B444`<user_input`Pre-defined data>`B333

Ta5d6ffAn empty input field: `B444`<demo_empty`>`B333

Ta5d6ffA sized input field: `B444`<16|with_size`>`B333

Ta5d6ffA masked input field: `B444`<!|masked_demo`hidden text>`B333

Ta5d6ffFull control: `B444`<!32|all_options`hidden text>`B333
Ta5d6ff`b

Ta5d6ff>>> Checkboxes

Ta5d6ffIn addition to text fields, Checkboxes are another way of submitting data. They allow the user to make a single selection or select multiple options.

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`<?|field_name|value`>`b Label Text`
Ta5d6ff`=
Ta5d6ffWhen the checkbox is checked, itTa5d6ff'Ta5d6ffs field will be set to the provided value. If there are multiple checkboxes that share the same field name, the checked values will be concatenated when they are sent to the node by a comma.
Ta5d6ff``

Ta5d6ff`B444`<?|sign_up|1`>`b Sign me up`

Ta5d6ffYou can also pre-check both checkboxes and radio groups by appending a |* after the field value.

Ta5d6ff`B444`<?|checkbox|1|*`>`b Pre-checked checkbox`

Ta5d6ff>>> Radio groups

Ta5d6ffRadio groups are another input that lets the user chose from a set of options. Unlike checkboxes, radio buttons with the same field name are mutually exclusive.

Ta5d6ffExample:

Ta5d6ff`=
Ta5d6ff`B900`<^|color|Red`>`b Red

Ta5d6ff`B090`<^|color|Green`>`b Green

Ta5d6ff`B009`<^|color|Blue`>`b Blue
Ta5d6ff`=

Ta5d6ffwill render:

Ta5d6ff`B900`<^|color|Red`>`b Red

Ta5d6ff`B090`<^|color|Green`>`b Green

Ta5d6ff`B009`<^|color|Blue`>`b Blue

Ta5d6ffIn this example, when the data is submitted, `B444` field_color`b will be set to whichever value from the list was selected.

Ta5d6ff``

Ta5d6ff>Comments

Ta5d6ffYou can insert comments that will not be displayed in the output by starting a line with the # character.

Ta5d6ffHereTa5d6ff'Ta5d6ffs an example:

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff# This line will not be displayed
Ta5d6ffThis line will
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffThe above markup produces the following output:

Ta5d6ff`Faaa`B333

Ta5d6ff# This line will not be displayed
Ta5d6ffThis line will

Ta5d6ff``


Ta5d6ff>Partials

Ta5d6ffYou can include partials in pages, which will load asynchronously once the page itself has loaded.

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`Ta5d6ff{Ta5d6fff64a846313b874ee4a357040807f8c77:/page/partial_1.mu}
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffItTa5d6ff'Ta5d6ffs also possible to set an auto-refresh interval for partials. Omit or set to 0 to disable. The following partial will update every 10 seconds.

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ff`Ta5d6ff{Ta5d6fff64a846313b874ee4a357040807f8c77:/page/refreshing_partial.mu`10}
Ta5d6ff`=
Ta5d6ff``

Ta5d6ffYou can include field values and variables in partial updates, and by setting the `!pid`! variable, you can create links that update one or more specific partials.

Ta5d6ff`Faaa
Ta5d6ff`=
Ta5d6ffName: `B444`<user_name`>`b

Ta5d6ff`F38a`[Say hello`p:32]`f

Ta5d6ff`Ta5d6ff{Ta5d6fff64a846313b874e84a357039807f8c77:/page/hello_partial.mu`0`pid=32|user_name}
Ta5d6ff`=
Ta5d6ff``

Ta5d6ff>Literals

Ta5d6ffTo display literal content, for example source-code, or blocks of text that should not be interpreted by micron, you can use literal blocks, specified by the Tffea00\\Ta5d6ff`= tag. Below is the source code of this entire document, presented as a literal block.

Ta5d6ff-

Ta5d6ff`=
Ta5d6ff'''
Te6edf3TOPIC_MARKUP Tff7b72+Tff7b72= Te6edf3TOPIC_MARKUPTff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Ta5d6ff`=Ta5d6ff"Tb4b4b4, Ta5d6ff"Tffea00\\Ta5d6ff`=Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff[ micron source for document goes here, we donTa5d6ff'Ta5d6fft want infinite recursion now, do we? ]Tffea00\nTffea00\\Ta5d6ff`=Ta5d6ff"
Te6edf3TOPIC_MARKUP Tff7b72+Tff7b72= Ta5d6ff"Tffea00\nTa5d6ff`=Tffea00\nTffea00\nTa5d6ff>Closing RemarksTffea00\nTffea00\nTa5d6ffIf you made it all the way here, you should be well equipped to write documents, pages and applications using micron and Nomad Network. Thank you for staying with me.Tffea00\nTa5d6ff"


Te6edf3TOPICS Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffIntroductionTa5d6ff"Tb4b4b4: Te6edf3TOPIC_INTRODUCTIONTb4b4b4,
Ta5d6ff"Ta5d6ffConcepts & TerminologyTa5d6ff"Tb4b4b4: Te6edf3TOPIC_CONCEPTSTb4b4b4,
Ta5d6ff"Ta5d6ffChannels & RRCTa5d6ff"Tb4b4b4: Te6edf3TOPIC_CHANNELSTb4b4b4,
Ta5d6ff"Ta5d6ffConversationsTa5d6ff"Tb4b4b4: Te6edf3TOPIC_CONVERSATIONSTb4b4b4,
Ta5d6ff"Ta5d6ffInterfacesTa5d6ff"Tb4b4b4: Te6edf3TOPIC_INTERFACESTb4b4b4,
Ta5d6ff"Ta5d6ffHosting a NodeTa5d6ff"Tb4b4b4: Te6edf3TOPIC_HOSTINGTb4b4b4,
Ta5d6ff"Ta5d6ffConfiguration OptionsTa5d6ff"Tb4b4b4: Te6edf3TOPIC_CONFIGTb4b4b4,
Ta5d6ff"Ta5d6ffKeyboard ShortcutsTa5d6ff"Tb4b4b4: Te6edf3TOPIC_SHORTCUTSTb4b4b4,
Ta5d6ff"Ta5d6ffMarkupTa5d6ff"Tb4b4b4: Te6edf3TOPIC_MARKUPTb4b4b4,
Ta5d6ff"Ta5d6ffDisplay TestTa5d6ff"Tb4b4b4: Te6edf3TOPIC_DISPLAYTESTTb4b4b4,
Ta5d6ff"Ta5d6ffNetwork ConfigurationTa5d6ff"Tb4b4b4: Te6edf3TOPIC_NETWORKSTb4b4b4,
Ta5d6ff"Ta5d6ffCredits & LicensesTa5d6ff"Tb4b4b4: Te6edf3TOPIC_LICENSESTb4b4b4,
Ta5d6ff"Ta5d6ffFirst RunTa5d6ff"Tb4b4b4: Te6edf3TOPIC_FIRST_RUNTb4b4b4,
Tb4b4b4}


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────